function R = kevaluate(label,Clusters,Truth)
	%
	% load kernel matrix K from space delimited file Kfile
	% calculate distance matrix (as U-vector. U as in LU factorisation)
	% cluster data (and display as dendrogram with labels from Lfile)
	% return cluster matrix
	%

	% store dataset label (a human readable name) to be used in the legend of plots etc.
	R.label = label;

	% create a logical matrix T indicating pairwise co-membership of same cluster
	T = sameclass(Truth);

	% for convenience, calculate positive (p) and negative (n) totals
	p = (sum(sum(T))-length(T))/2;   %-length(T) avoids counting x,x positives on diagonal
	n = sum(sum(T))/2;
	
	R.p = p;
	R.n = n;

	% extract cluster linkage distances (ignoring duplicates of same threshold)
	distances = unique(Clusters(:,3));
	len = length(distances);
	if len < 2
		% throw error
	end
	if distances(1) == 0
		% hack to make cluster()'s cutoff work for threshold of zero
		% (ie. leaves of tree where each instance is its own cluster)
		distances(1) = distances(2) / 2;
	end

	for i = 1:len
	
		% cut dendrogram at next linkage distance (increases monotonically)
		threshold = distances(i);
		HC = cluster(Clusters,'criterion', 'distance', 'cutoff',threshold);

		% create a logical matrix H indicating pairwise co-membership of same cluster
		H = sameclass(HC);

		tp = (sum(sum(T&H))-length(T))/2;   %-length(T) avoids counting x,x positives on diagonal
		fp = sum(sum(~T&H))/2;
		fn = sum(sum(T&~H))/2;
		tn = sum(sum(~(T|H)))/2;   %i.e. ~T&~H

		accuracy = (tp + tn) / (p + n);
 
		precision = tp/(tp + fp);
		recall    = tp/(tp + fn);

        if (precision+recall) > 0

            % f1-measure (f-score, f-measure)
            %alpha = 1;	% precision and recall weighted evenly
            %f1 = (1+alpha)*(precision*recall)/(alpha*precision + recall);
            f1 = 2*(precision*recall)/(precision + recall);

            % f2-measure
            alpha = 2;	% weights recall twice as much as precision
            f2 = (1+alpha)*(precision*recall)/(alpha*precision + recall);

            % f0.5-measure
            alpha = 0.5;	% precision weighted twice as much as recall
            f05 = (1+alpha)*(precision*recall)/(alpha*precision + recall);
        else
            f1  = 0;
            f2  = 0;
            f05 = 0;
        end
        
 		R.threshold(i)	= threshold;
		R.tp(i) 	= tp;
		R.fp(i) 	= fp;
		R.fn(i) 	= fn;
		R.tn(i) 	= tn;
		R.precision(i) 	= precision;
		R.recall(i) 	= recall;
		R.f1(i) 	= f1;
		R.f2(i) 	= f2;
		R.f05(i) 	= f05;
		R.accuracy(i)	= accuracy;
		
	end
	


	function L = sameclass(Classes)
		%
		% given a vector of instance class labels as int 1..#classes
		% create a logical matrix L indicating pairwise co-membership of same cluster
		%
		noofclusters = max(Classes);
		L = zeros(length(Classes),length(Classes));
		for c = 1:noofclusters
			cix = find(Classes == c);
			clen = length(cix);
			for j= 1:clen
				for k = 1:clen
					L(cix(j),cix(k)) = 1;
				end
			end
		end
	end


end